﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Text;

using MVCThemes.Interfaces;

using mvcForum.Core;
using mvcForum.Core.Abstractions.Interfaces;
using mvcForum.Core.Interfaces.Data;
using mvcForum.Core.Specifications;

using mvcForum.Web.Filters;

namespace mvcForum.Web.Extensions {

	public static class Extensions {

		/// <summary>
		/// Extensions returning a list of visible posts, based on the configuration.
		/// </summary>
		/// <param name="posts">All posts of a given topic.</param>
		/// <param name="config">The forum configuration.</param>
		/// <returns>The visible posts.</returns>
		public static IEnumerable<Post> Visible(this IEnumerable<Post> posts, IConfiguration config) {
			// Is the forum configured to show deleted posts?
			if (config.ShowDeletedMessages) {
				// Then all non-quarantined posts are visible!
				return posts.Where(p => p.FlagValue != (Int32)PostFlag.Quarantined);
			}

			// No, then we only show the "not flagged" posts.
			return posts.Where(p => p.FlagValue == (Int32)PostFlag.None);
		}

		public static String ForumImage(this UrlHelper url, string path) {
			// TODO: Get from settings!
			String forumImageRoot = "/content/img/forum/";
			String theme = DependencyResolver.Current.GetService<IThemeProvider>().GetTheme();
			if (!String.IsNullOrWhiteSpace(theme)) {
				String themeBaseURL = DependencyResolver.Current.GetService<IThemeURLProvider>().GetThemeBaseURL(theme);
				if (!String.IsNullOrWhiteSpace(themeBaseURL)) {
					forumImageRoot = String.Format("{0}gfx/", themeBaseURL);
				}
			}
			return url.Content(String.Format("{0}{1}", forumImageRoot, path));
		}
		#region Forum
		///// <summary>
		///// Extension for getting the AccessFlag for the given Forum.
		///// </summary>
		///// <param name="forum"></param>
		///// <returns></returns>
		//public static AccessFlag GetAccess(this Forum2 forum) {
		//    // Default access is: None!
		//    AccessFlag output = AccessFlag.None;

		//    // Let's get the UserProvider.
		//    IWebUserProvider userProvider = DependencyResolver.Current.GetService<IWebUserProvider>();
		//    // Any authenticated user?
		//    if (userProvider.Authenticated) {
		//        // Let's get the groups this user belongs to and OR the accessflags!
		//        // First the ElementRepository.
		//        IElementRepository elementRepository = DependencyResolver.Current.GetService<IElementRepository>();
		//        // Then the authenticated user.
		//        ForumUser user = elementRepository.ReadForumUser(userProvider.CurrentUserId);
		//        // Did we get a user?
		//        if (user != null) {
		//            // Let's get the list of groups this user belongs to.
		//            var groups = elementRepository.ReadGroups(user);

		//            foreach (var group in groups) {
		//                // Get the ForumAccess for the given groups!
		//                var forumAccess = elementRepository.ReadForumAccess(forum, group);
		//                if (forumAccess != null) {
		//                    // Let's OR them to get the correct access for the user!
		//                    output = output | forumAccess.AccessMask().AccessFlag;
		//                }
		//            }
		//        }
		//    }
		//    else {
		//        // Get the guest group and return the accessflag (if any!)
		//        Group group = DependencyResolver.Current.GetService<IElementRepository>().ReadGroup("Guest");
		//        ForumAccess access = forum.GetAccess(group);
		//        if (access != null) {
		//            output = access.AccessMask().AccessFlag;
		//        }
		//    }

		//    return output;
		//}

		///// <summary>
		///// Extension for determining if the user (if any) has the given access flag to the given forum.
		///// </summary>
		///// <param name="forum"></param>
		///// <param name="flag"></param>
		///// <returns></returns>
		//public static Boolean HasAccess(this Forum2 forum, AccessFlag flag) {
		//    return (forum.GetAccess() & flag) == flag;
		//}

		///// <summary>
		///// Extension for getting the ForumAccess for the given forum and group.
		///// </summary>
		///// <param name="forum"></param>
		///// <param name="group"></param>
		///// <returns></returns>
		//public static ForumAccess2 GetAccess(this Forum2 forum, Group group) {
		//    // Get the ElementRepository.
		//    IElementRepository elementRepository = DependencyResolver.Current.GetService<IElementRepository>();
		//    // Return the ForumAccess for the given group and forum.
		//    return elementRepository.ReadForumAccess(forum, group);
		//}
		#endregion

		#region Topic Extensions
		public static void SetSticky(this Topic topic) {
			AccessFlag flag = topic.Forum.GetAccess();
			if ((flag & AccessFlag.Priority) == AccessFlag.Priority) {
				topic.Type = TopicType.Sticky;
			}
		}

		public static void SetAnnouncement(this Topic topic) {
			AccessFlag flag = topic.Forum.GetAccess();
			if ((flag & AccessFlag.Priority) == AccessFlag.Priority) {
				topic.Type = TopicType.Announcement;
			}
		}

		public static void SetLocked(this Topic topic) {
			AccessFlag flag = topic.Forum.GetAccess();
			if ((flag & AccessFlag.Moderator) == AccessFlag.Moderator) {
				topic.SetFlag(TopicFlag.Locked);
			}
		}
		#endregion
	}
}